package com.jinbei.common.util;


import com.jinbei.common.annotation.AuthorAnnotation;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.File;
import java.io.IOException;
import java.lang.reflect.Method;
import java.net.URL;
import java.net.URLDecoder;
import java.util.*;

/**
 * @author zflu
 * 该工具类提供扫描controller后的author map
 * Created by lucky on 2018/7/18.
 */
public class AuthorAnnotationUtil {

    private static final Logger logger = LoggerFactory.getLogger(AuthorAnnotationUtil.class);

    private static final String PACKAGE_NAME = "com.jinbei.restController";

    private static Set<Class<?>> classes = null;

    private static Map<String ,Object> map = new HashMap();

    /**
     * @author zflu
     * @Description   获取author map
     * @date 2018/7/18 11:36
     * @param
     * @return java.util.Map
     */
    public static Map getAuthor(){
        //初始化
        init();
        if(null == classes || classes.size() == 0){
            return map;
        }
        for (Class<?> info :classes){
            //获取该类下方法集合
            Method[] methods = info.getMethods();
            List<Method> list = Arrays.asList(methods);
            if(null != list && list.size() > 0){
                List<Object> listArray = new ArrayList<>();
                String key = null;
                for (Method method : list){
                    Map<String,String> hashMap = new HashMap<>();
                    AuthorAnnotation author = method.getAnnotation(AuthorAnnotation.class);
                    //如果为null 或者不需要授权
                    if(null == author || !author.flag()){
                        continue;
                    }
                    //授权的url
                    String name = author.name();
                    String log = author.logs();
                    if(StringUtils.isNotBlank(name)){
                        try {
                            key = author.name().split("/")[1];
                        }catch (Exception e){
                            logger.error("注解name格式定义错误.........{}",e);
                        }
                    }
                    hashMap.put("url",name);
                    hashMap.put("name",log);
                    listArray.add(hashMap);
                }
                if(StringUtils.isNotBlank(key)){
                    map.put(key,listArray);
                }
            }
        }
        return map;
    }

    /**
     * @author zflu
     * @Description   获取controller包下的类
     * @date 2018/7/18 11:16
     * @param
     * @return void
     */
    private static void init(){
        classes = new LinkedHashSet<>();
        String packageDirName = PACKAGE_NAME.replace(".","/");
        Enumeration<URL> dirs;
        try {
            dirs = Thread.currentThread().getContextClassLoader().getResources(packageDirName);
            while (dirs.hasMoreElements()){
                java.net.URL url = dirs.nextElement();
                //获取协议
                String protocol = url.getProtocol();
                if("file".equals(protocol)){
                    logger.info("以File形式扫描......");
                    String filePath = URLDecoder.decode(url.getPath(),"UTF-8");
                    addClasses(PACKAGE_NAME,filePath,classes);
                }
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.info("权限参数初始化成功.........");
    }

    /**
     * @author zflu
     * @Description    迭代循环包,读取类的 classes
     * @date 2018/7/18 11:17
     * @param packageName  包路径
     * @param packagePath  物理路径
     * @param classes      class集合
     * @return void
     */
    private static void addClasses(String packageName,String packagePath,Set<Class<?>> classes){
        // 获取此包的目录 建立一个File
        File dir = new File(packagePath);
        // 如果不存在或者 也不是目录就直接返回
        if (!dir.exists() || !dir.isDirectory()) {
            logger.info("包名 " + packageName + " 下没有任何文件........");
            return;
        }
        // 如果存在 就获取包下的所有文件 包括目录
        File[] dirFiles = dir.listFiles();
        // 循环所有文件
        for (File file : dirFiles) {
            // 如果是目录 则继续扫描
            if (file.isDirectory()) {
                addClasses(packageName + "." + file.getName(), file.getAbsolutePath(), classes);
            } else {
                // 如果是java类文件 去掉后面的.class 只留下类名
                String className = file.getName().substring(0, file.getName().length() - 6);
                try {
                    // 添加到集合中去
                    classes.add(Thread.currentThread().getContextClassLoader().loadClass(packageName + '.' + className));
                } catch (ClassNotFoundException e) {
                    logger.error("找不到此类的.class文件..........");
                    e.printStackTrace();
                }
            }
        }
    }

    public static void main(String[] args) {
//        Map author = getAuthor();
//        System.out.println(author.toString());
    }
}
